package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    // Declaring variables
    ServerSocket serverSocket = null;

    Socket connectionSocket = null;

    final int PORT_NUMBER = 3500;

    PrintWriter printWriter = null;

    BufferedReader bufferedReader = null;

    BufferedReader serverInputReader = null;

    String userInput = null;

    //TODO verificar onde instanciar
    DeviceImpl device = new DeviceImpl();

    public static void main(String args[]) throws IOException {
        Server serverUsingSockets = new Server();
        serverUsingSockets.start();
    }

    private void start() throws IOException {
        try {
            // Listens here
            serverSocket = new ServerSocket(PORT_NUMBER);
            printMessage("Server started. Awaiting connection requests...");
        } catch (IOException ioexception) {
            // handle the exception
            // maybe you want to inform the user that there is a problem and exit here?
            printMessage("There is a problem starting the Server.");
            printMessage("Exception: " + ioexception);
            stopServer(1);
        }

        // Creates a socket for a client request
        connectionSocket = serverSocket.accept();
        printMessage("Server accepted connection from client.");

        printWriter = new PrintWriter(connectionSocket.getOutputStream(), true);
        bufferedReader = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

        ServerReader reader = new ServerReader();
        reader.start();

        ServerWriter writer = new ServerWriter();
        writer.start();
    }

    private void printMessage(String message) {
        System.out.println(message);
    }

    private void closeAllOpenStuff() throws IOException {
        printWriter.close();
        bufferedReader.close();
        connectionSocket.close();
        serverSocket.close();
    }

    private void stopServer(int exitValue) {
        printMessage("Exiting Server process.");
        System.exit(exitValue);
    }

    class ServerReader extends Thread {

        @Override
        public void run() {
            try {

                // This is the input being captured from the client
                while ((userInput = bufferedReader.readLine()) != null) {
                    printMessage("Received from client: " + userInput);

                    //interpretar comando do cliente
                    String response = executeCommand(userInput);
                    printWriter.println("Server responding with: "); // you can use your message to respond from server
                    printWriter.println(response);

                    if (userInput.equalsIgnoreCase("Exit") || userInput.equalsIgnoreCase("Bye") || userInput.equalsIgnoreCase("Quit")) {
                        // breaking here. But you can retain until there is a user-intervention to stop the server
                        break;
                    }
                }
                printMessage("Server stopped.");
                closeAllOpenStuff();
            } catch (IOException ioexception) {
                // there is a problem creating the connection socket that will
                // be used by the Client to communicate
                ioexception.printStackTrace();
            }

            stopServer(0);
        }

        private String executeCommand(String command) {
            return device.getMessage(command);
        }

    }

    class ServerWriter extends Thread {

        private BufferedReader keyboard;

        @Override
        public void run() {
            keyboard = new BufferedReader(new InputStreamReader(System.in));

            try {
                String keyboardMsg = keyboard.readLine();

                while (!keyboardMsg.equals("exit")) {
                    printMessage("Sending do client: " + keyboardMsg);

                    printWriter.println("Server responding with: " + keyboardMsg); // you can use your message to respond from server

                    keyboardMsg = keyboard.readLine();
                }

                stopServer(0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
